package com.wuliang.generate.common.core.basic;

import com.google.gson.JsonSyntaxException;
import com.wuliang.generate.common.core.response.Result;
import com.wuliang.generate.common.core.response.ResultUtils;
import com.wuliang.generate.common.core.response.ReturnCode;
import com.wuliang.generate.common.core.utils.VoUtils;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 抽象出来的controller类，下列方法和接口可以选择性重写，或者是继续沿用
 *
 * @param <E> 因系统事务性的要求，所以此处的实体类对象应为controller对应的实体类对象
 * @author 邬魉
 */
public abstract class BaseController<E extends BasicEntity, V extends BaseVo<E>> {

    @Autowired(required = false)
    private BaseRepository<E> jpa;

    @PostMapping("/findPageByKeywords")
    @ApiOperation(value = "根据关键字罗列分页列表")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "其他字段", dataType = "object", paramType = "body")
    })
    public Result<?> findPageByKeywords(@RequestBody V vo) {
        Sort sort;
        if (vo.getSortedField() != null) {
            sort = Sort.by(vo.getSortedField());
        } else {
            sort = Sort.by("createTime").descending();
        }
        Pageable pageable = PageRequest.of(vo.getPageNo() - 1, vo.getPageSize(), sort);
        return ResultUtils.success(jpa.findAll(vo.toSpecification(), pageable));
    }

    @PostMapping("/getEntityById/{id}")
    @ApiOperation(value = "根据ID获取数据详情", response = Result.class)
    @ApiImplicitParam(value = "数据ID", name = "id", dataType = "number", paramType = "path")
    public Result<?> getEntityById(@PathVariable(name = "id") Integer id, @RequestHeader("Token") String token) {
        Optional<E> entityOptional = jpa.findById(id);
        return entityOptional.map(ResultUtils::success).orElseGet(ResultUtils::dataEmptyError);
    }

    @PostMapping("/deleteOne/{id}")
    @ApiOperation(value = "删除单条数据", response = Result.class)
    @ApiImplicitParam(value = "数据ID", name = "id", dataType = "String", paramType = "path")
    public Result<?> deleteOne(@PathVariable("id") Integer id) {
        if (StringUtils.isEmpty(id)) {
            return ResultUtils.error(ReturnCode.PARAM_NOT_FOUND);
        }
        Optional<E> entityOptional = jpa.findById(id);
        if (!entityOptional.isPresent()) {
            return ResultUtils.dataEmptyError();
        }
        E entity = entityOptional.get();
        entity.setDataStatus(1);
        jpa.save(entity);
        return ResultUtils.success();
    }

    @PostMapping("/deleteOneByUser/{id}")
    @ApiOperation(value = "删除单条数据", response = Result.class)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "数据ID", name = "id", dataType = "String", paramType = "path"),
            @ApiImplicitParam(name = "Token", value = "Token", dataType = "string", paramType = " header")
    })
    public Result<?> deleteOneByUser(@PathVariable Integer id, @RequestHeader("Token") String token) {
        return deleteOne(id);
    }

    @PostMapping("/deleteByIdList")
    @ApiOperation(value = "批量删除", response = Result.class)
    @ApiImplicitParam(value = "被选中的数据ID数组", name = "ids", dataType = "String", paramType = "param", example = "\"[1, 2, 3, 4, 5]\"")
    public Result<?> deleteByIdList(@RequestBody V vo) {
        List<Integer> idList = vo.getIdList();
        List<E> entityList = new ArrayList<>();
        idList.forEach(id -> {
            Optional<E> entityOptional = jpa.findById(id);
            if (!entityOptional.isPresent()) {
                return;
            }
            E entity = entityOptional.get();
            entity.setDataStatus(1);
            entityList.add(entity);
        });
        if (entityList.size() != idList.size()) {
            return ResultUtils.error("批量删除失败!", ReturnCode.ERROR);
        }
        jpa.saveAll(entityList);
        return ResultUtils.success();
    }

    @PostMapping("/save")
    @ApiOperation(value = "保存实体类对象", response = Result.class)
    public Result<?> save(@RequestBody V vo) {
        E entity = VoUtils.voToEntity(vo);
        if (entity == null) {
            return ResultUtils.paramNotNull();
        }

        jpa.save(entity);
        return ResultUtils.success();
    }
}
